/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ntb.controllers;

import com.ntb.common.PaginationUtil;
import com.ntb.common.SecuredAction;
import com.ntb.controllers.forms.BuildingForm;
import com.ntb.entities.Buildings;
import com.ntb.entities.Lands;
import com.ntb.entities.PermitDetails;
import com.ntb.models.BuildingStatusDAO;
import com.ntb.models.BuildingTypesDAO;
import com.ntb.models.BuildingsDAO;
import com.ntb.models.LandPlansLaidDAO;
import com.ntb.models.LandStatusDAO;
import com.ntb.models.LandsDAO;
import com.ntb.models.LocationsDAO;
import com.ntb.models.PermitDetailDAO;
import com.ntb.models.impl.BuildingStatusDAOImpl;
import com.ntb.models.impl.BuildingTypesDAOImpl;
import com.ntb.models.impl.BuildingsDAOImpl;
import com.ntb.models.impl.LandPlansLaidDAOImpl;
import com.ntb.models.impl.LandStatusDAOImpl;
import com.ntb.models.impl.LandsDAOImpl;
import com.ntb.models.impl.LocationsDAOImpl;
import com.ntb.models.impl.PermitDetailDAOImpl;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

/**
 *
 * @author Thinh Hung
 */
public class BuildingAction extends SecuredAction {

    private List<String> errorMessages = new ArrayList();
    private List<String> successMessages = new ArrayList();

    @Override
    public ActionForward ntbExecute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {

        ActionForward forward = mapping.getInputForward();
        BuildingForm buildingForm = (BuildingForm) form;
        BuildingsDAO buildingDao = new BuildingsDAOImpl();
        String action = buildingForm.getAction();

        errorMessages = new ArrayList();
        successMessages = new ArrayList();


        if ("selectLand".equalsIgnoreCase(action)) {
            forward = selectLand(request, buildingForm, mapping);

        } else if ("savePermit".equalsIgnoreCase(action)) {
            // Save Permit Details
            Buildings building = buildingDao.getRow(buildingForm.getBuildingID());
            PermitDetailDAO permitDao = new PermitDetailDAOImpl();
            boolean isSuccess = true;

            PermitDetails permit = new PermitDetails();
            permit.setIssuerName(buildingForm.getIssuerName());
            permit.setIssuedDate(buildingForm.getIssuedDate());
            permit.setSignerName(buildingForm.getSignerName());
            permit.setDescription(buildingForm.getDescription());

            permit.setPermitID(building.getOccupancyPermitID());
            if (building.getOccupancyPermitID() > 0) {
                int id = permitDao.update(permit);
                if (id <= 0) {
                    isSuccess = false;
                }
            } else {
                int id = permitDao.add(permit);
                if (id > 0) {
                    buildingDao.updateOccupancyPermitID(building.getBuildingID(), id);
                    buildingDao.updateStatus(building.getBuildingID(), "RO");
                } else {
                    isSuccess = false;
                }
            }

            if (isSuccess) {
                if (buildingForm.getPermitID() > 0) {
                    successMessages.add("The permit has been saved.");
                } else {
                    successMessages.add("The permit has been added. The status of the building successfully updated.");
                }
            } else {
                errorMessages.add("An error occured, please try again later.");
            }
            forward = viewBuilding(buildingDao, buildingForm, request, mapping);
        } else if ("editOP".equalsIgnoreCase(action)) {
            // Show Edit Occupancy Permit Page

            Buildings building = buildingDao.getRow(buildingForm.getBuildingID());
            PermitDetailDAO permitDao = new PermitDetailDAOImpl();
            PermitDetails permit = permitDao.getRow(building.getOccupancyPermitID());
            forward = editPermit(buildingForm, permit, mapping);
        } else if ("save".equalsIgnoreCase(action)) {
            // Save

            forward = updateBuilding(buildingForm, buildingDao, request, mapping);
            if (forward == null) {
                forward = viewBuilding(buildingDao, buildingForm, request, mapping);
            }
        } else if ("save & exit".equalsIgnoreCase(action)) {
            // Save & Back to list

            forward = updateBuilding(buildingForm, buildingDao, request, mapping);
            forward = forward == null ? mapping.findForward("buildingListing") : forward;
        } else if ("edit".equalsIgnoreCase(action)) {
            // Show Edit Page

            forward = editBuilding(buildingDao, buildingForm, request, mapping);
        } else if ("UpdateStatus".equalsIgnoreCase(action)) {
            // Update Status

            if ("RO".equalsIgnoreCase(buildingForm.getStatusCode())) {
                forward = mapping.findForward("buildingPermitCreate");
            } else {
                if (buildingDao.updateStatus(buildingForm.getBuildingID(), buildingForm.getStatusCode()) > 0) {
                    successMessages.add("The status of the building successfully updated.");
                } else {
                    errorMessages.add("There was an error updating the status of this building. Can't re-update the status.");
                }
                forward = viewBuilding(buildingDao, buildingForm, request, mapping);
            }
        } else if (buildingForm.getBuildingID() > 0) {
            // Show Detail Page

            forward = viewBuilding(buildingDao, buildingForm, request, mapping);
        } else {
            // Show Add Page

            forward = addBuilding(buildingDao, buildingForm, request, mapping);
        }

        request.setAttribute("errorMessages", errorMessages);
        request.setAttribute("successMessages", successMessages);

        return forward;
    }

    /**
     * Load Add Page
     * 
     * @param request
     * @param buildingForm
     */
    private ActionForward addBuilding(BuildingsDAO buildingDao, BuildingForm buildingForm, HttpServletRequest request, ActionMapping mapping) {

        LandsDAO landDao = new LandsDAOImpl();
        if (landDao.checkExist(buildingForm.getLandID())) {

            request.setAttribute("land", landDao.getRow(buildingForm.getLandID()));

            BuildingTypesDAO typeDao = new BuildingTypesDAOImpl();
            request.setAttribute("buildingTypeList", typeDao.getList());

            BuildingStatusDAO statusDao = new BuildingStatusDAOImpl();
            request.setAttribute("statusList", statusDao.getStatusTable());

            buildingForm.setBuildingID(0);
            return mapping.getInputForward();
        } else {
            request.setAttribute("Please select a land when add the building.", this);
            return mapping.findForward("buildingListing");
        }

    }

    /**
     * Load Edit Building Page
     * 
     * @param buildingDao
     * @param buildingForm
     * @param request
     * @param mapping
     * @return
     */
    private ActionForward editBuilding(BuildingsDAO buildingDao, BuildingForm buildingForm, HttpServletRequest request, ActionMapping mapping) {
        ActionForward forward;
        LandsDAO landDao = new LandsDAOImpl();

        Buildings building = buildingDao.getRow(buildingForm.getBuildingID());
        request.setAttribute("land", landDao.getRow(building.getLandID()));

        buildingForm.setBuildingID(building.getBuildingID());
        buildingForm.setBuildingName(building.getBuildingName());
        buildingForm.setBuildingTypeID(building.getBuildingTypeID());
        buildingForm.setNumFloors(building.getNumFloors() + "");
        buildingForm.setNumRooms(building.getNumRooms() + "");
        buildingForm.setConstructedDate(building.getConstructedDate());
        buildingForm.setDescription(building.getDescription());

        BuildingTypesDAO typeDao = new BuildingTypesDAOImpl();
        request.setAttribute("buildingTypeList", typeDao.getList());

        BuildingStatusDAO statusDao = new BuildingStatusDAOImpl();
        request.setAttribute("statusList", statusDao.getStatusTable());

        forward = mapping.findForward("buildingEdit");
        return forward;
    }

    /**
     * Load Edit Permit Page
     * 
     * @param buildingForm
     * @param permitType
     * @param permit
     * @param mapping
     * @return
     */
    private ActionForward editPermit(BuildingForm buildingForm, PermitDetails permit, ActionMapping mapping) {
        ActionForward forward;

        buildingForm.setPermitID(permit.getPermitID());
        buildingForm.setIssuerName(permit.getIssuerName());
        buildingForm.setIssuedDate(permit.getIssuedDate());
        buildingForm.setSignerName(permit.getSignerName());
        buildingForm.setDescription(permit.getDescription());
        forward = mapping.findForward("buildingPermitEdit");
        return forward;
    }

    /**
     * select a land to add
     * @param request
     * @param buildingForm
     * @param mapping
     * @return
     */
    private ActionForward selectLand(HttpServletRequest request, BuildingForm buildingForm, ActionMapping mapping) {
        ActionForward forward;
        LandsDAO landDAO = new LandsDAOImpl();
        LocationsDAO locationsDao = new LocationsDAOImpl();
        request.setAttribute("locationList", locationsDao.getList());

        LandPlansLaidDAO planDao = new LandPlansLaidDAOImpl();
        request.setAttribute("planList", planDao.getList());

        LandStatusDAO statusDao = new LandStatusDAOImpl();
        request.setAttribute("statusList", statusDao.getStatusTable());

        String baseUrl = request.getRequestURI() + "?action=selectLand&amp;";

        String landID = null;
        String address = null;
        int planID = -1;
        int locationID = -1;
        int areaF = -1;
        int areaT = -1;
        int costF = -1;
        int costT = -1;
        String dateF = null;
        String dateT = null;
        String status = null;

        int page = -1;

        landID = buildingForm.getId();
        landID = "".equals(landID) ? null : landID;
        if (landID != null) {
            baseUrl += "id=" + landID + "&amp;";
        }

        address = buildingForm.getAdd();
        address = "".equals(address) ? null : address;
        if (address != null) {
            baseUrl += "add=" + address + "&amp;";
        }

        planID = buildingForm.getPlan();
        if (planID > 0) {
            baseUrl += "plan=" + planID + "&amp;";
        } else {
            planID = -1;
        }

        locationID = buildingForm.getLocation();
        if (locationID > 0) {
            baseUrl += "location=" + locationID + "&amp;";
        } else {
            locationID = -1;
        }

        try {
            areaF = Integer.parseInt(buildingForm.getAreaF());
        } catch (Exception e) {
        }
        if (areaF > 0) {
            baseUrl += "areaF=" + areaF + "&amp;";
        } else {
            areaF = -1;
        }

        try {
            areaT = Integer.parseInt(buildingForm.getAreaT());
        } catch (Exception ex) {
        }
        if (areaT > 0) {
            baseUrl += "areaT=" + areaT + "&amp;";
        } else {
            areaT = -1;
        }

        try {
            costF = Integer.parseInt(buildingForm.getCostF());
        } catch (Exception ex) {
        }
        if (costF > 0) {
            baseUrl += "costF=" + costF + "&amp;";
        } else {
            costF = -1;
        }

        try {
            costT = Integer.parseInt(buildingForm.getCostT());
        } catch (Exception e) {
        }
        if (costT > 0) {
            baseUrl += "costT=" + costT + "&amp;";
        } else {
            costT = -1;
        }

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            df.parse(buildingForm.getDateF());
            dateF = buildingForm.getDateF();
        } catch (Exception ex) {
            dateF = null;
        }
        if (dateF != null) {
            baseUrl += "dateF=" + dateF + "&amp;";
        }

        try {
            df.parse(buildingForm.getDateT());
            dateT = buildingForm.getDateT();
        } catch (Exception ex) {
            dateT = null;
        }
        if (dateT != null) {
            baseUrl += "dateT=" + dateT + "&amp;";
        }

        status = buildingForm.getStatus();
        status = "".equals(status) ? null : status;
        if (status != null) {
            baseUrl += "status=" + status + "&amp;";
        }

        try {
            int i = Integer.parseInt(request.getParameter("page"));
            page = i > 1 ? i : 1;
        } catch (Exception ex) {
        }

        Iterator<Lands> landList = landDAO.getList(landID, address, locationID, planID, areaF, areaT, costF, costT, dateF, dateT, status, page);
        request.setAttribute("landList", landList);

        PaginationUtil paginationUtil = new PaginationUtil();
        paginationUtil.setBaseUrl(baseUrl);
        paginationUtil.setNumPages(landDAO.getPageCount(landID, address, locationID, planID, areaF, areaT, costF, costT, dateF, dateT, status));
        paginationUtil.setCurPage(page);
        request.setAttribute("pagination", paginationUtil.createLinks());
        forward = mapping.findForward("buildingSelectLand");

        return forward;
    }

    /**
     * Update Building
     * 
     * @param buildingForm
     * @param buildingDao
     * @param mapping
     * @return
     */
    private ActionForward updateBuilding(BuildingForm buildingForm, BuildingsDAO buildingDao, HttpServletRequest request, ActionMapping mapping) {
        ActionForward forward;
        Buildings building = new Buildings();

        int landId = buildingForm.getLandID();

        LandsDAO landDao = new LandsDAOImpl();



        int numFloors = 0;
        try {
            numFloors = Integer.parseInt(buildingForm.getNumFloors());
        } catch (Exception ex) {
        }

        int numRooms = 0;
        try {
            numRooms = Integer.parseInt(buildingForm.getNumRooms());
        } catch (Exception ex) {
        }

        building.setBuildingID(buildingForm.getBuildingID());
        building.setLandID(landId);
        building.setBuildingTypeID(buildingForm.getBuildingTypeID());
        building.setBuildingName(buildingForm.getBuildingName());
        building.setNumFloors(numFloors);
        building.setNumRooms(numRooms);
        building.setConstructedDate(buildingForm.getConstructedDate());
        building.setDescription(buildingForm.getDescription());

        if (building.getBuildingID() > 0) {
            Buildings temp = buildingDao.getRow(building.getBuildingID());
            if (temp == null) {
                errorMessages.add("Building not found!");
                forward = mapping.findForward("buildingListing");
            } else {

                // check available
                boolean available = true;

                if (!temp.getBuildingName().equalsIgnoreCase(building.getBuildingName())) {
                    if (buildingDao.checkDuplicateName(building.getBuildingName())) {
                        available = false;
                        errorMessages.add("The building name you selected is already in use.");
                    }
                }

                if (available) {
                    buildingDao.update(building);
                    successMessages.add("The building \"" + building.getBuildingID() + "\" has been saved.");
                    return null;
                } else {
                    forward = editBuilding(buildingDao, buildingForm, request, mapping);
                }
            }
        } else {
            if (!landDao.checkExist(landId)) {
                errorMessages.add("The land does not exits. Please check the land and try again!");
                forward = addBuilding(buildingDao, buildingForm, request, mapping);
            } else {
                // check available
                boolean available = true;

                if (buildingDao.checkDuplicateName(building.getBuildingName())) {
                    available = false;
                    errorMessages.add("The building name you selected is already in use.");
                }

                if (available) {
                    buildingDao.add(building);
                    successMessages.add("The new building has been added.");
                    forward = mapping.findForward("buildingListing");
                } else {
                    forward = addBuilding(buildingDao, buildingForm, request, mapping);
                }
            }
        }
        return forward;
    }

    /**
     * Load Detail Page
     * 
     * @param buildingDao
     * @param buildingForm
     * @param request
     * @param mapping
     * @return
     */
    private ActionForward viewBuilding(BuildingsDAO buildingDao, BuildingForm buildingForm, HttpServletRequest request, ActionMapping mapping) {
        ActionForward forward;
        Buildings building = buildingDao.getRow(buildingForm.getBuildingID());
        request.setAttribute("building", building);

        LandsDAO landDAO = new LandsDAOImpl();
        request.setAttribute("land", landDAO.getRow(building.getLandID()));

        BuildingStatusDAO buildingStatusDao = new BuildingStatusDAOImpl();
        request.setAttribute("statusHistory", buildingStatusDao.getList(building.getBuildingID()));

        PermitDetailDAO permitDao = new PermitDetailDAOImpl();
        if (building.getOccupancyPermitID() > 0) {
            request.setAttribute("occupancyPermit", permitDao.getRow(building.getOccupancyPermitID()));
        }

        forward = mapping.findForward("buildingDetail");
        return forward;
    }
}